package com.java1234.util;

import java.math.BigDecimal;
import java.math.RoundingMode;

import static com.java1234.util.GeoTypeConverter.toBigDecimal;
import static jdk.nashorn.internal.runtime.JSType.toDouble;

public class GeoUtils {
    private static final double EARTH_RADIUS = 6378137; // 地球半径

    public static BigDecimal calculateDistance(BigDecimal lng1, BigDecimal lat1,
                                               BigDecimal lng2, BigDecimal lat2) {
        double distance = calculateDistance(lng1.doubleValue(), lat1.doubleValue(),
                lng2.doubleValue(), lat2.doubleValue());
        return new BigDecimal(distance).setScale(2, RoundingMode.HALF_UP);
    }
    private static double calculateDistance(double lng1, double lat1,
                                            double lng2, double lat2) {
        // Haversine公式计算距离（代码同上文）
        double distance = GeoUtils.getDistance(
                toDouble(lng1),
                toDouble(lat1),
                toDouble(lng2),
                toDouble(lat2)
        );
        return distance;
    }
    // 基础版（double参数）
    public static double getDistance(double lng1, double lat1,
                                     double lng2, double lat2) {
        double radLat1 = Math.toRadians(lat1);
        double radLat2 = Math.toRadians(lat2);
        double a = radLat1 - radLat2;
        double b = Math.toRadians(lng1) - Math.toRadians(lng2);

        double distance = 2 * Math.asin(Math.sqrt(
                Math.pow(Math.sin(a / 2), 2) +
                        Math.cos(radLat1) * Math.cos(radLat2) *
                                Math.pow(Math.sin(b / 2), 2)
        ));

        return (distance * EARTH_RADIUS);
    }

    // 增强版（BigDecimal参数）
    public static BigDecimal getDistanceExact(
            BigDecimal lng1, BigDecimal lat1,
            BigDecimal lng2, BigDecimal lat2
    ) {
        double result = getDistance(
                lng1.doubleValue(),
                lat1.doubleValue(),
                lng2.doubleValue(),
                lat2.doubleValue()
        );
        return new BigDecimal(result).setScale(2, RoundingMode.HALF_UP);
    }
}